package com.cloudeye.im.service;

import com.cloudeye.im.dto.ChatRecordRootDTO;
import com.cloudeye.im.type.AccountRelationEnum;
import com.cloudeye.im.vo.ImGroup;
import com.cloudeye.im.vo.ImRoom;
import com.easemob.im.server.EMProperties;
import com.easemob.im.server.EMService;
import com.easemob.im.server.api.group.GroupApi;
import com.easemob.im.server.api.room.RoomApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.util.FileCopyUtils;
import reactor.core.publisher.Mono;

import javax.annotation.processing.Filer;
import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;

/**
 * 环信接口
 */
@Slf4j
public class EasemobIntegrationService implements ImIntegrationService{

    EMProperties properties = EMProperties.builder()
            .setAppkey("1121210819094760#demo")
            .setClientId("YXA6Ae6iUveJQbeR5W8YPCzsnQ")
            .setClientSecret("YXA6iia1OBUKYmqbQfuz_cqzy3w4PHg")
            .build();
    EMService service = new EMService(properties);
    Duration timeout = Duration.ofSeconds(10);

    @Override
    public void createAccount(String userName, String password) {
        service.user().create(userName,password).block(timeout);
    }

    @Override
    public void updateOnlineOffLine(String userName, String status) {
        //更新数据库
    }

    @Override
    public void addAccountRelation(String owner, String user, AccountRelationEnum type) {
        if(AccountRelationEnum.BLOCK.equals(type)){
            service.block().blockUserSendMsgToUser(owner,user).block(timeout);
        }
        if(AccountRelationEnum.FRIEND.equals(type)){
            service.contact().add(owner,user);
        }
    }

    @Override
    public void removeAccountRelation(String owner, String user, AccountRelationEnum type) {
        if(AccountRelationEnum.BLOCK.equals(type)){
            service.block().unblockUserSendMsgToUser(owner,user).block(timeout);
        }
        if(AccountRelationEnum.FRIEND.equals(type)){
            service.contact().remove(owner,user).block(timeout);
        }
    }

    @Override
    public String createGroup(ImGroup imGroup) {
        GroupApi groupApi = service.group();
        String groupId = null;
        if(imGroup.isPublic()){
            groupId = groupApi.createPublicGroup(imGroup.getOwner(), imGroup.getName(), imGroup.getDescription(),
                    imGroup.getMembers(), imGroup.getMaxusers(), imGroup.isInviteNeedConfirm())
                    .block(timeout);
        }else {
            groupId = groupApi.createPrivateGroup(imGroup.getOwner(),imGroup.getName(),imGroup.getDescription(),
                    imGroup.getMembers(),imGroup.getMaxusers(),imGroup.isInviteNeedConfirm())
            .block(timeout);
        }
        return groupId;
    }

    @Override
    public void addGroupUsers(String groupId, List<String> users) {
        GroupApi groupApi = service.group();
        users.forEach(t->{
            groupApi.addGroupMember(groupId,t).block(timeout);
        });
    }

    @Override
    public void addGroupAdmins(String groupId, List<String> admins) {
        GroupApi groupApi = service.group();
        admins.forEach(t->{
            groupApi.addGroupAdmin(groupId,t).block(timeout);
        });
    }


    @Override
    public void addGroupBlock(String group, String blockUser) {
        service.block().blockUserJoinGroup(blockUser,group).block(timeout);
    }

    @Override
    public void removeGroupBlock(String group, String blockUser) {
        service.block().unblockUserJoinGroup(blockUser,group).block(timeout);
    }

    @Override
    public void removeGroup(String group) {
        service.group().destroyGroup(group).block(timeout);
    }

    @Override
    public void createRoom(ImRoom imRoom) {
        service.room().createRoom(imRoom.getName(),imRoom.getDescription(),imRoom.getOwner(),
                imRoom.getMembers(),imRoom.getMaxMembers()).block(timeout);
    }

    @Override
    public void addRoomUsers(String room, List<String> users) {
        RoomApi roomApi = service.room();
        users.forEach(t->{
            roomApi.addRoomMember(room,t).block(timeout);
        });
    }

    @Override
    public void addRoomAdmins(String room, List<String> admins) {
        RoomApi roomApi = service.room();
        admins.forEach(t->{
            roomApi.promoteRoomAdmin(room,t).block(timeout);
        });
    }

    @Override
    public void addRoomBlock(String room, String blockUser) {
        service.block().blockUserJoinRoom(blockUser,room).block(timeout);
    }

    @Override
    public void removeRoomBlock(String room, String blockUser) {
        service.block().unblockUserJoinRoom(room,blockUser).block(timeout);
    }

    @Override
    public void removeRoom(String room) {
        service.room().destroyRoom(room).block(timeout);
    }

    @Override
    public void syncChatRecord(Instant instant) {
    }

    /**
     * 从环信服务器下载到本地
     * @param instant
     * @return
     */
    private File downLoadChatRecordFromEaseCloud(Instant instant){
        Path path = FileSystems.getDefault().getPath("path");
        //默认文件名为2021082419.gz
        Mono<Path> file = service.message().getHistoryAsLocalFile(instant, path, null);
        return file.block(timeout).toFile();
    }

    /**
     * 从文件读取消息内容
     * @param file
     * @return
     */
    public  List<ChatRecordRootDTO> readFromFile(File file) throws IOException {
        List<String> resultList = Lists.newArrayList();
        BufferedReader br = new BufferedReader(new FileReader(file));
        String str;
        while ((str = br.readLine())!=null){
            resultList.add(str);
        }
        return resultList.stream().map(t->new ChatRecordRootDTO().convert(t))
                .collect(Collectors.toList());
    }

    /**
     * 将聊天记录上传到业务服务器
     * @param file
     * @return
     */
    private String uploadFileToCloud(File file){
        String serverUrl = null;
        return serverUrl;
    }


}
